package com.shuqi.download.core;

import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;

import com.shuqi.download.database.DownloadInfo;
import com.shuqi.download.database.DownloadInfoDao;
import com.shuqi.download.listener.BlockStateListener;
import com.shuqi.download.util.Constant;
import com.shuqi.download.util.Util;

/**
 * 文件块下载线程
 * @author GaoPeng<gaopeng@ucweb.com>
 *
 */
public class BlockThread implements Runnable {

    private BlockStateListener listener;
    private DownloadInfo downloadInfo;
    // 读取网络流缓冲区大小（WIFI下下载速度4096比1024提升70%，8192比4096提升50%，但越大越耗内存）
    private final static int BUFFER_SIZE=8192;
    
    BlockThread(BlockStateListener listener,DownloadInfo downloadInfo) {
        this.listener=listener;
        this.downloadInfo=downloadInfo;
    }
    
    public void start() {
        Util.log("<<<<<<运行块下载线程（"+downloadInfo+"）");
        HttpURLConnection conn=Util.getConnection(downloadInfo.getFileUrl(), (downloadInfo.getPosStart()+downloadInfo.getDownLength()) + "-"+ downloadInfo.getPosEnd(), 1, 2);
        if(conn!=null) {
            try {
                Util.log("接收数据块大小（"+conn.getHeaderField("Content-Length")+"）");
                Util.log("接收Range（"+conn.getHeaderField("Content-Range")+"）");
                InputStream is = conn.getInputStream();
                byte[] buffer = new byte[BUFFER_SIZE];
                int offset = 0;
                RandomAccessFile file = new RandomAccessFile(Constant.CACHE_PATH+"/"+Util.parseFileName(downloadInfo.getUserId(), downloadInfo.getBookId()), "rwd");
                file.seek(downloadInfo.getPosStart()+downloadInfo.getDownLength());
                while ((offset = is.read(buffer,0,BUFFER_SIZE)) != -1) {
                    // 接受干扰信号时退出线程
                    if(Thread.currentThread().isInterrupted()) {
                        Util.log("探测到干扰信号（退出）");
                        break;
                    }
                    file.write(buffer, 0, offset);
                    downloadInfo.setDownLength(downloadInfo.getDownLength()+offset);
                    // 下载进度实时回传
                    listener.updateDownState(offset);
                }
                file.close();
                is.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 标记线程下载已完成
                int totalLength=downloadInfo.getPosEnd()-downloadInfo.getPosStart()+1;
                float downPercent=Util.getPercent(downloadInfo.getDownLength(), totalLength);
                downloadInfo.setDownloadPercent(downPercent);
                if(downloadInfo.getDownLength()>=totalLength||downPercent==100) {
                    downloadInfo.setDownloadStatus(1);
                }
                DownloadInfoDao.getInstance().update(downloadInfo);
                Util.log("数据块下载完成（"+downloadInfo.getDownLength()+"）>>>");
                conn.disconnect();
            }
        } else {
            Util.log("下载块网络连接获取失败（"+downloadInfo.getFileUrl()+"）");
        }
        Util.log("块下载线程执行完毕（"+downloadInfo+"）>>>>>>");
    }
    
    @Override
    public void run() {
        // 线程运行未完成时重试次数
        int retry=2;
        int i=0;
        start();
        while(downloadInfo.getDownloadStatus()!=1&&i<retry) {
            if(Thread.currentThread().isInterrupted()) {
                Util.log("探测到干扰信号（退出）");
                break;
            }
            i++;
            Util.log("第"+i+"次重新运行块下载线程（"+downloadInfo.getId()+"）");
            start();
        }
    }
}